#pragma once

#include "Containers/Map.h"
#include "GenericInfo.h"

#include "Type.h"
#include "DecoratedType.h"

//type of TPair<key,value>
class WHENGINE_API CPairType: public CType
{
public:
    CPairType();

    static CPairType* GetStaticType();

    static CString CreateTypeName(const CString& KeyType, const CString& ValueType);
    static STypeID CreateID(const SDecoratedType & KeyType, const SDecoratedType & ValueType);

protected:
    static CString PlaceholderNameKey;
    static CString PlaceholderNameValue;   

};

class WHENGINE_API CPairGeneralized : public CType
{
public:
    //ValueOffset is the offset of the value in the pair
    //if set to 0, the offset is calculated automatically
    //in c++, offset ! =sizeof(key), because of the padding
    CPairGeneralized(
        const SDecoratedType& InKeyType
        ,const SDecoratedType& InValueType
        ,int64_t ValueOffset=0
        );

    const SDecoratedType& GetKeyType();
    const SDecoratedType& GetValueType();

    static CPairGeneralized * FindPairType(const SDecoratedType& InKeyType,const SDecoratedType& InValueType);
    static CPairGeneralized * FindOrAddType(const SDecoratedType& InKeyType,const SDecoratedType& InValueType, int64_t ValueOffset);

    uint64_t GetKeyHash(const void* InPair);

    //only erase the value, not the key
    void EraseValue(void* InPair);
    //only clone the value, not the key
    void CloneValue(const void* InScrPair,void* InDestPair);

    void CloneKeyAndValue(const void* InScrKey,
        const void* InScrValue  ,
        void* InDestPair);

    void* GetKeyPtr(void* InPair);
    void * GetValuePtr(const void* InPair);

    bool IsKeyEqual(const void* InPair1,const void* InPair2);
    bool IsValueEqual(const void* InPair1,const void* InPair2);

    int64_t GetValueOffset() const { return ValueOffset; }
protected:
    int64_t ValueOffset=0;

};